package com.zhunaer.dao.impl;

import com.zhunaer.dao.OrderDao;
import com.zhunaer.entity.Order;
import com.zhunaer.utils.JDBCUtils;

import java.sql.*;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Date;

/**
 * 订单数据访问对象实现类
 *
 * <p>提供订单数据的持久化操作，包括：
 * <ul>
 *   <li>订单创建与状态更新</li>
 *   <li>订单信息查询</li>
 *   <li>关联的用户余额操作</li>
 * </ul>
 */
public class OrderDaoImpl implements OrderDao {

    /**
     * 创建新订单
     *
     * @param order 包含订单信息的实体对象
     * @return 返回生成的订单ID，创建失败返回-1
     * @throws RuntimeException 当数据库操作失败时抛出
     */
    @Override
    public int createOrder(Order order) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = JDBCUtils.getConnection();
            String sql = "INSERT INTO orders(user_id, room_id, amount, status) VALUES(?,?,?,?)";
            pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            pstmt.setInt(1, order.getUserId());
            pstmt.setInt(2, order.getRoomId());
            pstmt.setBigDecimal(3, order.getAmount());
            pstmt.setString(4, order.getStatus());

            int affectedRows = pstmt.executeUpdate();
            if (affectedRows > 0) {
                rs = pstmt.getGeneratedKeys();
                if (rs.next()) {
                    return rs.getInt(1);
                }
            }
            return -1;
        } catch (SQLException e) {
            throw new RuntimeException("创建订单失败", e);
        } finally {
            JDBCUtils.close(conn, pstmt, rs);
        }
    }

    /**
     * 更新订单状态
     *
     * @param orderId 要更新的订单ID
     * @param status 新的订单状态
     * @return 受影响的行数
     * @throws RuntimeException 当数据库操作失败时抛出
     */
    @Override
    public int updateOrderStatus(int orderId, String status) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = JDBCUtils.getConnection();
            String sql = "UPDATE orders SET status = ? WHERE order_id = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, status);
            pstmt.setInt(2, orderId);
            return pstmt.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException("更新订单状态失败", e);
        } finally {
            JDBCUtils.close(conn, pstmt, null);
        }
    }

    /**
     * 根据订单ID查询订单详情
     *
     * @param orderId 要查询的订单ID
     * @return 订单实体对象，未找到返回null
     * @throws RuntimeException 当数据库操作失败时抛出
     */
    @Override
    public Order findOrderById(int orderId) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = JDBCUtils.getConnection();
            String sql = "SELECT * FROM orders WHERE order_id = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, orderId);
            rs = pstmt.executeQuery();

            if (rs.next()) {
                Order order = new Order();
                order.setOrderId(rs.getInt("order_id"));
                order.setUserId(rs.getInt("user_id"));
                order.setRoomId(rs.getInt("room_id"));
                order.setAmount(rs.getBigDecimal("amount"));
                order.setStatus(rs.getString("status"));
                order.setOrderTime(new Date(rs.getTimestamp("order_time").getTime()));
                order.setCheckInTime(rs.getTimestamp("check_in_time") != null ?
                        new Date(rs.getTimestamp("check_in_time").getTime()) : null);
                order.setCancelTime(rs.getTimestamp("cancel_time") != null ?
                        new Date(rs.getTimestamp("cancel_time").getTime()) : null);
                return order;
            }
            return null;
        } catch (SQLException e) {
            throw new RuntimeException("查询订单失败", e);
        } finally {
            JDBCUtils.close(conn, pstmt, rs);
        }
    }

    /**
     * 查询指定用户的所有订单
     *
     * @param userId 用户ID
     * @return 订单列表，按下单时间降序排列
     * @throws RuntimeException 当数据库操作失败时抛出
     */
    @Override
    public List<Order> findOrdersByUser(int userId) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<Order> orders = new ArrayList<>();
        try {
            conn = JDBCUtils.getConnection();
            String sql = "SELECT * FROM orders WHERE user_id = ? ORDER BY order_time DESC";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, userId);
            rs = pstmt.executeQuery();

            while (rs.next()) {
                Order order = new Order();
                order.setOrderId(rs.getInt("order_id"));
                order.setUserId(rs.getInt("user_id"));
                order.setRoomId(rs.getInt("room_id"));
                order.setAmount(rs.getBigDecimal("amount"));
                order.setStatus(rs.getString("status"));
                order.setOrderTime(new Date(rs.getTimestamp("order_time").getTime()));
                orders.add(order);
            }
            return orders;
        } catch (SQLException e) {
            throw new RuntimeException("查询用户订单失败", e);
        } finally {
            JDBCUtils.close(conn, pstmt, rs);
        }
    }

    /**
     * 扣减用户余额（用于订单支付）
     *
     * @param userId 用户ID
     * @param amount 扣减金额
     * @return 受影响的行数（1表示成功，0表示余额不足）
     * @throws RuntimeException 当数据库操作失败时抛出
     */
    @Override
    public int deductBalance(int userId, BigDecimal amount) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = JDBCUtils.getConnection();
            String sql = "UPDATE users SET balance = balance - ? WHERE user_id = ? AND balance >= ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setBigDecimal(1, amount);
            pstmt.setInt(2, userId);
            pstmt.setBigDecimal(3, amount);
            return pstmt.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException("扣减余额失败", e);
        } finally {
            JDBCUtils.close(conn, pstmt, null);
        }
    }

    /**
     * 更新订单金额
     *
     * @param orderId 订单ID
     * @param amount 新的订单金额
     * @return 受影响的行数
     * @throws RuntimeException 当数据库操作失败时抛出
     */
    @Override
    public int updateAmount(int orderId, BigDecimal amount) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = JDBCUtils.getConnection();
            String sql = "UPDATE orders SET amount = ? WHERE order_id = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setBigDecimal(1, amount);
            pstmt.setInt(2, orderId);
            return pstmt.executeUpdate();
        } catch (SQLException e) {
            throw new RuntimeException("更新订单金额失败", e);
        } finally {
            JDBCUtils.close(conn, pstmt, null);
        }
    }
}